package com.ponchware.classes
{
	import com.ponchware.classes.events.TankFireEvent;
	import com.ponchware.classes.weapons.Shell;
	import com.ponchware.interfaces.IMoveable;
	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.Point;
	import flash.ui.Keyboard;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Image;
	import mx.core.UIComponent;
	import mx.effects.Rotate;
	
	[Event(name="fire", type="com.ponchware.classes.events.TankFireEvent")]
	public class Tank extends UIComponent implements IMoveable
	{
		
		
		// Images
		[Embed(source="com/ponchware/sprites/greentank_right.gif")]
		private var imgTankRight:Class;
		
		[Embed(source="com/ponchware/sprites/greentank_left_noturret.png")]
		private var imgTankLeft:Class;
		
		[Embed(source="com/ponchware/sprites/turret_left.png")]
		private var imgTurretLeft:Class;
		
		[Embed(source="com/ponchware/mp3/tank_driving.mp3")]
		private var mp3TankDriving:Class;
		
		[Embed(source="com/ponchware/mp3/tank_fire.mp3")]
		private var mp3TankFiring:Class;
		
		[Bindable]
		private var tankSprites:ArrayCollection = new ArrayCollection([imgTankLeft, imgTankRight]);
		
		//[Bindable]
		//public var direction:Number = DIRECTION_RIGHT;
		private var _direction:Number;
		public static const DIRECTION_LEFT:Number = 0;
		public static const DIRECTION_RIGHT:Number = 1;
		
		// Member variables
		private var terrain:Terrain
		private var img:Image;
		private var turret:Image;
		
		// Movement vars
		private var yspeed:Number = 0;
		private var xspeed:Number = 2;
		private const GRAVITY:Number = .2;
		
		private var moving:Boolean = false;
		
		// Weapon vars
		private var turret_angle:Number = 0;
		private var turret_power:Number = 100;
		
		public function Tank(terrain:Terrain)
		{
			super();
			this.width = 39;
			this.height = 30;
			this.terrain = terrain;
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		protected override function createChildren():void
		{
			super.createChildren();
			img = new Image();
			img.width = 39;
			img.height = 39
			img.source = tankSprites[DIRECTION_RIGHT];
			this.addChild(img);
			
			turret = new Image();
			turret.width = 15;
			turret.height = 7;
			turret.y = 4;
			turret.source = imgTurretLeft;
			this.addChild(turret);
		}
		
		
		
		public function set direction(dir:Number):void
		{
			if (dir == Tank.DIRECTION_LEFT)
			{
				_direction = dir;
			}
			else if (dir == Tank.DIRECTION_RIGHT)
			{
				_direction = dir;
			}
			
			img.source = tankSprites[_direction];
		}
		
		
		// Event handlers
		public function onKeyDown(e:KeyboardEvent):void
		{
				this.setFocus();
				switch (e.keyCode)
				{
					// Handle driving
					case Keyboard.RIGHT:
					case Keyboard.LEFT:
						handleDriving(e);
						break;
						
					case Keyboard.UP:
					case Keyboard.DOWN:
						handleAiming(e);
						break;
						
					// Handle firing
					case Keyboard.SPACE:
						handleFiring(e);
						break;
				}
		}
		
		public function onKeyUp(e:KeyboardEvent):void
		{
			switch (e.keyCode)
			{
				case Keyboard.LEFT:
				case Keyboard.RIGHT:
					moving = false;
					SoundManager.stopSound(mp3TankDriving);
					break;
			}
			
		}
		
		private function onEnterFrame(e:Event):void
		{
			// Check position of tank
			var p:Point = new Point(this.x + this.width/2, this.y + this.height);
			if (!terrain.ground.hitTestPoint(p.x, p.y, true))
			{
				this.y+= yspeed;
				yspeed += GRAVITY;
			}
			else
			{
				yspeed = 0;
			}
		}
		
		
		
		// Key handlers (driving, aiming, firing, etc)
		private function handleDriving(e:KeyboardEvent):void
		{
			trace(this.parent);
			if (!moving)
			{
				this.setFocus();
				SoundManager.playSound(mp3TankDriving, 3000, true);
				moving = true;
			}
			
			if (e.keyCode == Keyboard.RIGHT)
			{
				this.x += xspeed;
				this.direction = Tank.DIRECTION_RIGHT;
			}
			else if (e.keyCode == Keyboard.LEFT)
			{
				this.x -= xspeed;
				this.direction = Tank.DIRECTION_LEFT;
			}
			
			while (terrain.ground.hitTestPoint(this.x+this.width/2, this.y + this.height, true))
			{
				this.y-= yspeed;
				yspeed += GRAVITY;
			}
		}
		
		private function handleFiring(e:KeyboardEvent):void
		{
			SoundManager.playSound(mp3TankFiring, 350);
			var radians:Number = turret_angle * Math.PI / 180;
			// Adjust for flash players backwards measurement of angle
				radians = Math.PI - radians;
			this.dispatchEvent(new TankFireEvent(TankFireEvent.FIRE, Shell.WEAPON_TYPE, radians, turret_power / 100));
		}
		
		private function handleAiming(e:KeyboardEvent):void
		{
			var rot:Rotate = new Rotate();
			
			if (e.keyCode == Keyboard.UP)
			{
				// Increasing angle
				if (_direction == DIRECTION_LEFT && turret_angle < 90)
					turnTurret(turret_angle + 1);
				else if (_direction == DIRECTION_RIGHT && turret_angle >= 90)
					turnTurret(turret_angle - 1);
			}
			else
			{
				// Decreasing angle
				if (_direction == DIRECTION_LEFT && turret_angle >= 0)
					turnTurret(turret_angle - 1);
				else if (_direction == DIRECTION_RIGHT && turret_angle < 180)
					turnTurret(turret_angle + 1);
			}
		}
		
		private function turnTurret(angle:Number):void
		{
			var rot:Rotate = new Rotate();
			
			rot.originX = 17;
			rot.originY = 4;
			rot.duration = 1;
			rot.angleFrom = turret_angle;
			rot.angleTo = turret_angle = angle;
			rot.play([turret]);
		}
	}
}